home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctj8509.arc / EGA_PRIM.INC < prev    next >
Text File  |  1985-08-29  |  6KB  |  188 lines

  1. {**** An include file that contains EGA Graphics primitives. ****}
  2.  
  3. TYPE
  4.    RegisterPack = RECORD
  5.           AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : INTEGER
  6.        END;
  7.  
  8. VAR
  9.    Rec : RegisterPack;
  10.    Xaddr : ARRAY[0..639] OF INTEGER;
  11.    Yaddr : ARRAY[0..349] OF INTEGER;
  12.    Point : ARRAY[0..639] OF INTEGER;
  13.  
  14.  
  15. PROCEDURE Init_graphics;
  16. VAR
  17.    indx     : INTEGER;
  18.    switches : BYTE;
  19.    info     : BYTE;
  20.    mono     : BOOLEAN;
  21. BEGIN
  22.    switches := MEM[$40 : $88] AND $0F;
  23.    info     := MEM[$40 : $87];
  24.    { mono is TRUE if monochrome display attached to EGA }
  25.    mono   := ODD((info AND $02) SHR 1);
  26.    { now we set up registers for the mode set based on }
  27.    { switch settings and information byte bits }
  28.    IF mono THEN rec.ax := $000F  { 640 X 350 monochrome }
  29.    ELSE WITH rec DO
  30.      CASE switches OF
  31.        6 : ax := $0D;   { Color 40 X 25 -- 320 X 200 }
  32.        7 : ax := $0E;   { Color 80 X 25 -- 640 X 200 }
  33.        8 : ax := $10;   { Enhanced color -- normal mode }
  34.        9 : ax := $10;   { Enhanced color -- enhanced mode
  35.        ELSE rec.ax := $0E;  { Default to "safe" 640 X 200 mode}
  36.      END; { CASE }
  37.    INTR($10,rec);
  38.    {**** Arrays used to avoid repetitive address calculations.}
  39.    FOR indx := 0 TO 349 DO Yaddr[indx] := 80*indx;
  40.    FOR indx := 0 TO 639 DO Xaddr[indx] := indx DIV 8;
  41.    FOR indx := 0 TO 639 DO Point[indx] := $80 SHR (indx MOD 8)
  42. END;
  43.  
  44.  
  45. PROCEDURE plot( x, y : INTEGER);
  46. VAR
  47.    total : INTEGER;
  48. BEGIN
  49.    total := Xaddr[x] + Yaddr[y];
  50.    {**** EGA memory is sequential starting at $A000.}
  51.    MEM[$A000: total] := point[x] OR MEM[$a000: total]
  52. END;
  53.  
  54.  
  55. PROCEDURE switch(VAR first, second : INTEGER);
  56. VAR
  57.    temp : INTEGER;
  58. BEGIN
  59.    temp := first;
  60.    first := second;
  61.    second := temp
  62. END;
  63.  
  64.  
  65. PROCEDURE draw( xx1, yy1, xx2, yy2 : INTEGER);
  66. VAR
  67.    Lg_delta, Sh_delta, Cycle, Lg_step, Sh_step, dtotal : INTEGER;
  68. BEGIN
  69.    {**** Set up deltas and steps according to the relationship of
  70.                          (X1, Y1) and (X2, Y2).}
  71.    Lg_delta := xx2 - xx1;   Sh_delta := yy2 - yy1;
  72.    IF Lg_delta < 0 THEN
  73.         BEGIN
  74.            Lg_delta := -Lg_delta;   Lg_step := -1
  75.         END
  76.       ELSE  Lg_step := 1;
  77.    IF Sh_delta < 0 THEN
  78.         BEGIN
  79.            Sh_delta := -Sh_delta;   Sh_step := -1
  80.         END
  81.       ELSE  Sh_step := 1;
  82.    IF Sh_delta < Lg_delta THEN
  83.       BEGIN
  84.          {**** Here is the expected case of a longer X-axis so make
  85.                cycle = large_delta/2 and do the normal increments.}
  86.          cycle := lg_delta SHR 1;
  87.          WHILE xx1 <> xx2 DO
  88.             BEGIN
  89.                {**** While the endpoints do not meet Plot and make
  90.                                           the usual increments.}
  91.                dtotal := Xaddr[xx1] + Yaddr[yy1];
  92.                MEM[$A000: dtotal] := point[xx1] OR MEM[$a000: dtotal];
  93.                xx1 := xx1 + Lg_step;   cycle := cycle + Sh_delta;
  94.                IF cycle > Lg_delta THEN
  95.                   BEGIN
  96.                      yy1 := yy1 + Sh_step;  cycle := cycle - Lg_delta
  97.                   END
  98.             END
  99.       END
  100.     ELSE
  101.       BEGIN
  102.          {**** This is the reverse of what we expect so make the
  103.               cycle = short_delta/2 and switch deltas and steps.}
  104.          cycle := sh_delta SHR 1;
  105.          switch(lg_delta, Sh_delta);
  106.          switch(lg_step, sh_step);
  107.          WHILE yy1 <> yy2 DO
  108.             BEGIN
  109.                {**** While the endpoints do not meet Plot and make the
  110.                                            increments.}
  111.                dtotal := Xaddr[xx1] + Yaddr[yy1];
  112.                MEM[$A000: dtotal] := point[xx1] OR MEM[$A000: dtotal];
  113.                yy1 := yy1 + lg_step;   cycle := cycle + sh_delta;
  114.                IF cycle > lg_delta THEN
  115.                   BEGIN
  116.                      cycle := cycle - lg_delta;  xx1 := xx1 + sh_step
  117.                   END
  118.             END
  119.       END
  120. END;
  121.  
  122.  
  123. FUNCTION isqrt( arg : INTEGER) : INTEGER;  {**** Returns the integer
  124.                                            sqrt without using reals.}
  125. VAR
  126.    odd_int, old_arg, first_sqrt : INTEGER;
  127. BEGIN
  128.    odd_int := 1;  old_arg := arg;
  129.    WHILE arg >= 0 DO
  130.       BEGIN
  131.          arg := arg - odd_int;
  132.          odd_int := odd_int + 2;
  133.       END;
  134.    first_sqrt := odd_int SHR 1;
  135.    {**** Now a fixup to take care of overshoots.}
  136.    IF SQR(first_sqrt) - first_sqrt + 1 > old_arg
  137.         THEN isqrt := first_sqrt - 1 ELSE isqrt := first_sqrt
  138. END;
  139.  
  140.  
  141. PROCEDURE circle( cx, cy, radius : INTEGER);
  142. VAR
  143.    a, af, b, bf, target, r2 : INTEGER;
  144. BEGIN
  145.     target := 0;   a := radius;   b := 0;   r2 := sqr(radius);
  146.     WHILE a >= b DO
  147.        BEGIN
  148.           b := ROUND(sqrt(r2 - sqr(a))); {**** Use Isqrt(r2 - sqr(a)) here
  149.                                          if you do not have the 8087 chip.}
  150.           switch( target, b);
  151.           WHILE b < target DO {**** Inner loop takes care of straight lines
  152.                                       at cardinal points.}
  153.              BEGIN
  154.                 {**** Put in aspect correction and make use of the symmetry
  155.                     of a circle by plotting 8 points for each calculation.}
  156.                 af := 120*a DIV 100;   bf := 120*b DIV 100;
  157.                 plot(cx + af, cy + b);  plot(cx + bf, cy + a);
  158.                 plot(cx - af, cy + b);  plot(cx - bf, cy + a);
  159.                 plot(cx - af, cy - b);  plot(cx - bf, cy - a);
  160.                 plot(cx + af, cy - b);  plot(cx + bf, cy - a);
  161.                 b := b + 1;
  162.              END;
  163.           a := a - 1;
  164.        END
  165. END;
  166.  
  167.  
  168. PROCEDURE Screen_dump;
  169. VAR
  170.     xindx, yindx : INTEGER;
  171.     init_char : STRING[4];
  172. BEGIN
  173.    {**** The next two lines are for the Epson FX, JX, and MX with
  174.                   GrafTrax+. }
  175.    WRITELN(LST,CHR(27)+'A'+CHR(7));
  176.    WRITELN(lst,chr(27)+'2');
  177.    INIT_CHAR := CHR(27)+'K'+CHR(94)+CHR(1);
  178.    FOR xindx := 0 TO 79 DO
  179.      BEGIN
  180.         WRITE(LST, init_char);
  181.         FOR yindx:=349 DOWNTO 0 DO
  182.               WRITE(LST,CHR(MEM[$A000: Yaddr[yindx]+xindx]));
  183.         WRITELN(LST);
  184.      END;
  185.    WRITELN(LST,CHR(27) + '@');  {**** Clear printer attributes.}
  186.    WRITELN(LST);
  187. END;
  188.